package cn.slipi.admin.biz;

import cn.slipi.admin.biz.vo.permission.AuthPermissionVo;
import cn.slipi.admin.biz.vo.permission.PermissionModuleVo;
import cn.slipi.admin.biz.vo.permission.PermissionVo;
import cn.slipi.admin.biz.vo.permission.RoleVo;
import cn.slipi.admin.common.dto.PageDTO;
import cn.slipi.admin.common.utils.cache.constants.RedisConstants;
import cn.slipi.admin.common.utils.cache.redis.RedisClient;
import cn.slipi.admin.common.utils.dozer.impl.ConvertBean;
import cn.slipi.admin.constants.AdminConstants;
import cn.slipi.admin.controller.form.permission.*;
import cn.slipi.admin.entity.TSysPermissionModule;
import cn.slipi.admin.entity.TSysRole;
import cn.slipi.admin.service.TSysMenuService;
import cn.slipi.admin.service.TSysPermissionService;
import cn.slipi.admin.service.dto.in.m.*;
import cn.slipi.admin.service.dto.out.PermissionDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限业务层
 */
@Component
public class PermissionBiz {


    @Autowired
    private ConvertBean convertBean;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private TSysMenuService menuService;

    @Autowired
    private TSysPermissionService permissionService;


    private final static Logger LOG = LoggerFactory.getLogger(PermissionBiz.class);

    public List<AuthPermissionVo> getPermissionListAuth(Integer rid) {
        List<AuthPermissionVo> authPermissionVoListParent = new ArrayList<>();
        //获取模块
        List<TSysPermissionModule> permissionModuleList = this.permissionService.getPermissionModuleDropList();
        List<Integer> moduleIds = permissionModuleList.stream().map(TSysPermissionModule::getId).collect(Collectors.toList());
        //权限列表
        List<PermissionDTO> permissionList = redisClient.getList(AdminConstants.AUTH_PERMISSION, PermissionDTO.class);
        if (null == permissionList) {
            permissionList = this.permissionService.getPermissionAll();
            redisClient.set(AdminConstants.AUTH_PERMISSION, permissionList);
        }
        //根据模块ID分组
        Map<Integer, List<PermissionDTO>> permissionGroup = permissionList.stream().collect(Collectors.groupingBy(PermissionDTO::getModuleId));
        if (permissionGroup.containsKey(0)) {
            TSysPermissionModule permissionModule = new TSysPermissionModule();
            permissionModule.setId(0);
            permissionModule.setName("无模块权限");
            permissionModule.setDesc("无模块权限");
            permissionModuleList.add(permissionModule);
        }
        //构造菜单结构
        permissionModuleList.forEach(permissionModule -> {
            if (permissionGroup.containsKey(permissionModule.getId())) {
                List<PermissionDTO> mapPermissionList = permissionGroup.get(permissionModule.getId());
                List<AuthPermissionVo> authPermissionVoListChild = new ArrayList<>();
                //获取当前角色权限
                List<PermissionDTO> curRolePermissionList = this.permissionService.getPermissionByRoleId(rid);
                List<Integer> permissionIds = new ArrayList<>();
                if (curRolePermissionList.size() > 0) {
                    permissionIds = curRolePermissionList.stream().map(PermissionDTO::getId).collect(Collectors.toList());
                } else {
                    permissionIds = new ArrayList<>();
                }
                List<Integer> fPermissionIds = permissionIds;
                mapPermissionList.forEach(permission -> {
                    AuthPermissionVo authPermissionVoChild = permissionMapAuthMenu(permission, fPermissionIds);
                    authPermissionVoChild.setIsLast(true);
                    authPermissionVoListChild.add(authPermissionVoChild);
                });
                //获取当前用户菜单
                AuthPermissionVo authPermissionVoParent = menuMapAuthModule(permissionModule, moduleIds, authPermissionVoListChild);
                authPermissionVoParent.setIsLast(false);
                authPermissionVoParent.setChildren(authPermissionVoListChild);
                authPermissionVoListParent.add(authPermissionVoParent);
            }
        });
        return authPermissionVoListParent;
    }


    private AuthPermissionVo menuMapAuthModule(TSysPermissionModule module, List<Integer> moduleIds, List<AuthPermissionVo> authPermissionVoList) {
        AuthPermissionVo authPermissionVo = new AuthPermissionVo();
        authPermissionVo.setId(module.getId() + 10000000);
        authPermissionVo.setLevel(0);
        authPermissionVo.setTitle(module.getName());
        authPermissionVo.setParentId(0);
        if (authPermissionVoList.size() > 0) {
            boolean isCheck = false;
            for (AuthPermissionVo child : authPermissionVoList) {
                List<Map<String, String>> mapList = child.getCheckArr();
                if (mapList.size() > 0) {
                    Map<String, String> checkMap = mapList.get(0);
                    if ("1".equals(checkMap.get("isChecked"))) {
                        isCheck = true;
                    }
                }
            }
            if (isCheck) {
                authPermissionVo.setCheckArr(getPermissionCheckArr(1, new ArrayList<Integer>() {{
                    add(1);
                }}));
            } else {
                authPermissionVo.setCheckArr(getPermissionCheckArr(1, new ArrayList<Integer>() {{
                    add(0);
                }}));
            }
        } else {
            authPermissionVo.setCheckArr(getPermissionCheckArr(module.getId(), moduleIds));
        }
        authPermissionVo.setChildren(new ArrayList<>());
        return authPermissionVo;
    }

    private AuthPermissionVo permissionMapAuthMenu(PermissionDTO permission, List<Integer> permissionIds) {
        AuthPermissionVo authPermissionVo = new AuthPermissionVo();
        authPermissionVo.setId(permission.getId());
        authPermissionVo.setLevel(1);
        authPermissionVo.setTitle(permission.getName());
        authPermissionVo.setParentId(permission.getModuleId() + 10000000);
        List<Map<String, String>> permissionCheckArr = getPermissionCheckArr(permission.getId(), permissionIds);
        authPermissionVo.setCheckArr(permissionCheckArr);
        authPermissionVo.setChildren(new ArrayList<>());
        return authPermissionVo;
    }

    private List<Map<String, String>> getPermissionCheckArr(Integer id, List<Integer> ids) {
        List<Map<String, String>> checkArr = new ArrayList<>();
        Map<String, String> check = new HashMap<>();
        if (null == id) {
            check.put("type", "0");
            check.put("isChecked", "0");
        } else {
            if (ids.contains(id)) {
                check.put("type", "0");
                check.put("isChecked", "1");
            } else {
                check.put("type", "0");
                check.put("isChecked", "0");
            }
        }
        checkArr.add(check);
        return checkArr;
    }


    public PageDTO<PermissionVo> getPermissionList(PermissionQueryForm permissionQueryForm) {
        PermissionQueryDTO permissionQueryDTO = this.convertBean.convert(permissionQueryForm, PermissionQueryDTO.class);
        PageDTO<PermissionDTO> page = this.permissionService.getPermissionList(permissionQueryDTO);
        return PageDTO.of(page, permission -> this.convertBean.convert(permission, PermissionVo.class));
    }

    public PageDTO<PermissionModuleVo> getPermissionModuleList(ModuleQueryForm moduleQueryForm) {
        ModuleQueryDTO moduleQueryDTO = this.convertBean.convert(moduleQueryForm, ModuleQueryDTO.class);
        IPage<TSysPermissionModule> page = this.permissionService.getPermissionModuleList(moduleQueryDTO);
        return PageDTO.of(page, permissionModule -> this.convertBean.convert(permissionModule, PermissionModuleVo.class));
    }

    public List<PermissionModuleVo> getPermissionModuleDropList() {
        List<TSysPermissionModule> list = this.permissionService.getPermissionModuleDropList();
        return this.convertBean.convert(list, PermissionModuleVo.class);
    }

    public Integer addModule(ModuleSaveForm moduleSaveForm) {
        ModuleSaveDTO moduleSaveDTO = this.convertBean.convert(moduleSaveForm, ModuleSaveDTO.class);
        return this.permissionService.addModule(moduleSaveDTO);
    }

    public Boolean updateModule(Integer mid, ModuleSaveForm moduleSaveForm) {
        ModuleSaveDTO moduleSaveDTO = this.convertBean.convert(moduleSaveForm, ModuleSaveDTO.class);
        return this.permissionService.updateModule(mid, moduleSaveDTO);
    }

    public Boolean deleteModule(Integer mid) {
        return this.permissionService.deleteModule(mid);
    }

    public List<PermissionVo> getPermissionListByUserId(Integer adminId) {
        List<PermissionDTO> permissionList = this.permissionService.getPermissionByAdminId(adminId);
        return this.convertBean.convert(permissionList, PermissionVo.class);
    }

    public PageDTO<RoleVo> getRoleList(RoleQueryForm roleQueryForm) {
        RoleQueryDTO roleQueryDTO = this.convertBean.convert(roleQueryForm, RoleQueryDTO.class);
        IPage<TSysRole> page = this.permissionService.getRoleList(roleQueryDTO);
        return PageDTO.of(page, role -> this.convertBean.convert(role, RoleVo.class));
    }

    public Integer addPermission(PermissionSaveForm permissionSaveForm) {
        PermissionSaveDTO permissionSaveDTO = this.convertBean.convert(permissionSaveForm, PermissionSaveDTO.class);
        return this.permissionService.addPermission(permissionSaveDTO);
    }


    public Boolean updatePermission(Integer pid, PermissionSaveForm permissionSaveForm) {
        PermissionSaveDTO permissionSaveDTO = this.convertBean.convert(permissionSaveForm, PermissionSaveDTO.class);
        return this.permissionService.updatePermission(pid, permissionSaveDTO);
    }

    public Boolean updatePermissionModule(String pids, Integer mid) {
        List<String> permissionIds = Arrays.asList(pids.split(","));
        permissionIds.forEach(id -> {
            this.permissionService.updatePermissionModule(id, mid);
        });
        //删除缓存
        this.redisClient.deleteByKey(AdminConstants.AUTH_PERMISSION);
        return true;
    }

    public Integer addRole(RoleSaveForm roleSaveForm) {
        RoleSaveDTO roleSaveDTO = this.convertBean.convert(roleSaveForm, RoleSaveDTO.class);
        return this.permissionService.addRole(roleSaveDTO);
    }


    public Boolean updateRole(Integer rid, RoleSaveForm roleSaveForm) {
        RoleSaveDTO roleSaveDTO = this.convertBean.convert(roleSaveForm, RoleSaveDTO.class);
        return this.permissionService.updateRole(rid, roleSaveDTO);
    }

    public Boolean powerRoleAuth(Integer rid, RoleAuthSaveForm roleAuthSaveForm) {
        //处理权限
        this.permissionService.saveRolePermission(rid, roleAuthSaveForm.getPermissionIds());
        //处理菜单
        this.menuService.saveRoleMenu(rid, roleAuthSaveForm.getMenuIds());

        return true;
    }

}
